package com.atguigu.spzx.manager.service.impl;

import com.alibaba.fastjson.JSON;
import com.atguigu.spzx.common.exception.GuiguException;
import com.atguigu.spzx.manager.mapper.SysUserMapper;
import com.atguigu.spzx.manager.service.SysUserService;
import com.atguigu.spzx.model.dto.system.LoginDto;
import com.atguigu.spzx.model.entity.system.SysUser;
import com.atguigu.spzx.model.vo.common.ResultCodeEnum;
import com.atguigu.spzx.model.vo.system.LoginVo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.util.DigestUtils;

import java.util.UUID;
import java.util.concurrent.TimeUnit;

/**
 * 用户服务实现类
 */
@Service
public class SysUserServiceImpl implements SysUserService {
    // 注入用户映射器
    @Autowired
    private SysUserMapper sysUserMapper;
    // 注入Redis模板用于操作Redis缓存
    @Autowired
    private RedisTemplate<String, String> redisTemplate;

    /**
     * 用户登录方法
     *
     * @param loginDto 登录数据传输对象，包含用户名和密码
     * @return 登录成功后返回登录视图对象，包含用户唯一标识token
     * @throws RuntimeException 如果用户名不存在或密码不正确，则抛出运行时异常
     */
    @Override
    public LoginVo login(LoginDto loginDto) {
        // 1 获取提交用户名,从loginDto中获取
        String userName = loginDto.getUserName();
        // 2 根据用户名查询数据库表
        SysUser sysUser = sysUserMapper.selectUserInfoByUserName(userName);
        // 3 如果根据用户名查询不到对应信息，用户不存在，返回错误信息
        if (sysUser == null) {
            throw new GuiguException(ResultCodeEnum.LOGIN_ERROR);
        }
        // 4 如果根据用户名查询到对应信息，用户存在
        // 5 获取输入的密码，比较输入的密码和数据库密码是否一致
        String database_password = sysUser.getPassword();
        String input_password = loginDto.getPassword();
        // 把输入的密码进行加密，再比较数据库密码，使用MD5加密
        input_password = DigestUtils.md5DigestAsHex(input_password.getBytes());
        // 比较加密后的密码
        if (!input_password.equals(database_password)) {
            throw new GuiguException(ResultCodeEnum.LOGIN_ERROR);
        }
        // 6 如果密码一致，登录成功，如果不一致则登录失败
        // 7 登录成功，生成用户唯一标识token
        String token = UUID.randomUUID().toString().replaceAll("-", "");
        // 8 把登录成功用户信息放到Redis里面
        // key : token   value: 用户信息
        redisTemplate.opsForValue()
                .set("user:login" + token,
                        JSON.toJSONString(sysUser),
                        7,
                        TimeUnit.DAYS);
        // 9 返回LoginVo对象，包含token
        LoginVo loginVo = new LoginVo();
        loginVo.setToken(token);

        return loginVo;
    }
}
